/* * RedirectableStream.java * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2009–2012 Steinbeis Forschungszentrum (STZ Ölbronn), * Copyright (c) 2006–2012 by Michael Hoffer * * This file is part of Visual Reflection Library (VRL). * * VRL is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. * * see: http://opensource.org/licenses/LGPL-3.0 * file://path/to/VRL/src/eu/mihosoft/vrl/resources/license/lgplv3.txt * * VRL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * This version of VRL includes copyright notice and attribution requirements. * According to the LGPL this information must be displayed even if you modify * the source code of VRL. Neither the VRL Canvas attribution icon nor any * copyright statement/attribution may be removed. * * Attribution Requirements: * * If you create derived work you must do three things regarding copyright * notice and author attribution. * * First, the following text must be displayed on the Canvas: * "based on VRL source code". In this case the VRL canvas icon must be removed. * * Second, the copyright notice must remain. It must be reproduced in any * program that uses VRL. * * Third, add an additional notice, stating that you modified VRL. In addition * you must cite the publications listed below. A suitable notice might read * "VRL source code modified by YourName 2012". * * Note, that these requirements are in full accordance with the LGPL v3 * (see 7. Additional Terms, b). * * Publications: * * M. Hoffer, C.Poliwoda, G.Wittum. Visual Reflection Library - * A Framework for Declarative GUI Programming on the Java Platform. * Computing and Visualization in Science, 2011, in press. */ package eu.mihosoft.vrl.fxscad; import java.io.OutputStream; import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; import java.util.logging.Level; import java.util.logging.Logger; import javafx.application.Platform; import javafx.scene.control.TextArea; /** * * @author Michael Hoffer <info@michaelhoffer.de> */ public class RedirectableStream extends PrintStream { public static PrintStream ORIGINAL_SOUT = System.out; public static PrintStream ORIGINAL_SERR = System.err; private final List<TextArea> views = new ArrayList<TextArea>(); private boolean redirectToUi; private boolean redirectToStdOut; private final List<OutputFilter> filters = new ArrayList<>(); public RedirectableStream(OutputStream out, TextArea... views) { super(out); this.views.clear(); for (TextArea textArea : views) { addView(textArea); } setRedirectToStdOut(true); } @Override public synchronized void write(byte[] buf, int off, int len) { if (isRedirectToUi()) { invokeAndWait(() -> { int i = 0; for (TextArea view : views) { String s = new String(buf, off, len); if (filters.get(i).onMatch(s)) { try { int startOffSet = view.getText().length(); view.insertText(startOffSet, s); } catch (IllegalArgumentException e) { e.printStackTrace(); } } i++; } }); // view.setCaretPosition(startOffSet + len); // } // catch (BadLocationException e) { // e.printStackTrace(); // Platform.invokeLater(new Runnable() { // // @Override // public void run() { // // automatically scroll down to the last line //// view.scrollRectToVisible( //// new Rectangle(0, view.getHeight() - 1, 1, 1)); // // } // }); } if (isRedirectToStdOut()) { super.write(buf, off, len); } } public final void addView(TextArea view) { views.add(view); filters.add((OutputFilter) (String s) -> { return true; }); } public void setFilter(TextArea view, OutputFilter filter) { int i = views.indexOf(view); filters.set(i, filter); } /** * @return the redirectToUi */ public boolean isRedirectToUi() { return redirectToUi; } /** * @param redirectToUi the redirectToUi to set */ public void setRedirectToUi(boolean redirectToUi) { this.redirectToUi = redirectToUi; } /** * @return the redirectToStdOut */ public boolean isRedirectToStdOut() { return redirectToStdOut; } /** * @param redirectToStdOut the redirectToStdOut to set */ public final void setRedirectToStdOut(boolean redirectToStdOut) { this.redirectToStdOut = redirectToStdOut; } private static void invokeAndWait(Runnable r) { if (Platform.isFxApplicationThread()) { r.run(); } else { FutureTask<Boolean> task = new FutureTask<>(r, true); Platform.runLater(task); try { task.get(); // like join() } catch (InterruptedException | ExecutionException ex) { Logger.getLogger(RedirectableStream.class.getName()).log(Level.SEVERE, null, ex); } } } }